import gradio as gr
import pandas as pd
import numpy as np
import time
from ultralytics import YOLO
import os
import subprocess
import uuid
from shutil import copy
import cv2
from utils.request_util import query_plate
from car_type import car_type_recognition
from velocity import process_videocity
# 重新定义UPLOAD_PATH和DETECT_PATH
UPLOAD_PATH = os.path.join(os.path.dirname(__file__), 'static/upload')
DETECT_PATH = os.path.join(os.path.dirname(__file__), 'static/result')
os.makedirs(UPLOAD_PATH, exist_ok=True)
os.makedirs(DETECT_PATH, exist_ok=True)
# 生成UUID的函数
def generate_uuid():
    return str(uuid.uuid4())
# 文件拷贝命令
def file_copy(src, dest):
    copy(src, dest)
def get_video_filename(video_path):
    return os.path.basename(video_path)
# 加载模型
model = YOLO('yolov8n.pt')

# 检测图片中的车牌以及该车牌的归属地
def process_image(img):
    # 先生成一个UUID
    uuid_path = generate_uuid()
    # 使用os.makedirs递归地创建目录
    os.makedirs(UPLOAD_PATH + "/" + uuid_path)
    os.makedirs(DETECT_PATH + "/" + uuid_path)
    filename = 'uploaded_image.jpg'
    file_path = os.path.join(UPLOAD_PATH + "/" + uuid_path, filename)
    # 将 RGB 转换为 BGR
    image_bgr = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
    cv2.imwrite(file_path, image_bgr)
    # 要执行的yolo命令 实现运行detect_plate 文件里的 main函数内的内容 并修改了图片上传和保存路径
    predict_command = [
        'python',
        'detect_plate.py',
        '--detect_model',
        'weights/plate_detect.pt',
        '--rec_model',
        'weights/plate_rec_color.pth',
        '--image_path',
        UPLOAD_PATH + "/" + uuid_path,
        '--output',
        'static/result/' + uuid_path
        ]
    try:
        # 超时时间是20分钟
        subprocess.run(predict_command, shell=True, timeout=1200)
        # 获取要返回的检测后的图片路径
        dected_img = 'static/result/' + uuid_path + '/uploaded_image.jpg'
        # dected_img = 'static/upload/' + uuid_path + '/uploaded_image.jpg'
        # 返回视频路径即可
        return dected_img
    except subprocess.CalledProcessError as e:
        return e.stderr

def process_video(video):
    # 假设处理这些输入并返回结果
    # 先生成一个UUID
    uuid_path = generate_uuid()
    # 使用os.makedirs递归地创建目录
    os.makedirs(UPLOAD_PATH + "/" + uuid_path)
    os.makedirs(DETECT_PATH + "/" + uuid_path)
    # 如果是视频则保存上传的视频
    print(get_video_filename(video))
    video_filename = get_video_filename(video)
    file_copy(video, os.path.join(UPLOAD_PATH + "/" + uuid_path, video_filename))
    # 要执行的yolo命令
    predict_command = [
        'python',
        'detect_plate.py',
        '--detect_model',
        'weights/plate_detect.pt',
        '--rec_model',
        'weights/plate_rec_color.pth',
        '--video',
        'static/upload/' + uuid_path + '/' + video_filename,
        # 是不是上传成功的视频文件地址
        '--output',
        'static/result/' + uuid_path
        ]
    try:
        # 超时时间是20分钟
        subprocess.run(predict_command, timeout=1200)
        result_video_path = os.path.join('', 'result.mp4')
        dest_video_path = os.path.join('static/result/' + uuid_path, video_filename)
        file_copy(result_video_path, dest_video_path)
        # 获取要返回的视频文件路径
        video = 'static/result/' + uuid_path + '/' + video_filename
        # 返回视频路径即可
        return video
    except subprocess.CalledProcessError as e:
        return e.stderr

def yes(message, history):
    # 调用Home_search函数，并传递message作为参数
    response = query_plate(message)
    # 返回Home_search函数的返回值
    return response

def vote(data: gr.LikeData):
    if data.liked:
        print("You upvoted this response: " + data.value["value"])
    else:
        print("You downvoted this response: " + data.value["value"])

# 创建Gradio Blocks界面
with gr.Blocks() as demo:
    with gr.TabItem("车牌查询"):
        # 创建一个聊天机器人
        chatbot = gr.Chatbot(placeholder="<strong>您好！欢迎使用智能车牌查询业务<br>感谢您的支持")
        # 为聊天机器人添加点赞和点踩功能
        chatbot.like(vote, None, None)
        # 创建聊天页面
        gr.ChatInterface(fn=yes, chatbot=chatbot, title="智能车牌查询")

    with gr.TabItem("车牌图像识别"):
        iface_img = gr.Interface(
            fn=process_image,
            inputs=[gr.Image(label="上传图片")],
            outputs=[gr.Image(label="检测后的图片")],
            title="基于 YOLOv8的车牌检测系统",
            description="上传图像进行车牌检测"
        )

    with gr.TabItem("车牌视频识别"):
        iface_video = gr.Interface(
            fn=process_video,
            inputs=[gr.Video(label="上传视频")],
            outputs=[gr.Video(label="检测后的视频")],
            title="基于 YOLOv8的车牌检测系统",
            description="上传视频进行车牌检测"
        )

    with gr.TabItem("车型识别"):
        iface = gr.Interface(
            fn=car_type_recognition,
            inputs=gr.Image(type="filepath", label="选择图片"),
            outputs="text",
            title="车型识别系统"
        )
    with gr.TabItem("车辆测速"):
        iface_velocity = gr.Interface(
            fn=process_videocity,
            inputs=[gr.Video(label="上传视频")],
            outputs=[gr.Video(label="检测后的视频")],
            title="车速测试系统"
        )


# 定义端口号
gradio_port = 8080
gradio_url = f"http://127.0.0.1:{gradio_port}"
demo.launch(
    server_name="127.0.0.1",
    server_port=gradio_port,
    debug=True,
    auth=("admin", "123456"),
    auth_message="欢迎使用 YOLOv8的车牌检测系统",
    inbrowser=False,
    prevent_thread_lock=True,
    share=True
)
